Package org.python.modules.sets

Source Code of org.python.modules.sets.BaseSet

package org.python.modules.sets;

import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyIgnoreMethodTag;
import org.python.core.PyList;
import org.python.core.PyObject;
import org.python.core.PyTuple;
import org.python.core.__builtin__;
import org.python.core.PyType;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public abstract class BaseSet extends PyObject /*implements Set*/{

    /**
     * The underlying container.  HashSet is used rather than Set because
     * clone is protected on Object and I didn't want to cast.
     */
    protected HashSet _set;

    /**
     * Create a new, empty set instance.
     */
    public BaseSet() {
        super();
        this._set = new HashSet();
    }

    /**
     * Create a new set instance from the values of the iterable object.
     *
     * @param data An iterable instance.
     */
    public BaseSet(PyObject data) {
        super();
        this._set = new HashSet();
        this._update(data);
    }

    public BaseSet(PyType type) {
        super(type);
        this._set = new HashSet();
    }

    /**
     * Update the underlying set with the contents of the iterable.
     *
     * @param data An iterable instance.
     * @throws PyIgnoreMethodTag Ignore.
     */
    protected void _update(PyObject data) throws PyIgnoreMethodTag {

        if (data instanceof BaseSet) {
            // Skip the iteration if both are sets
            this._set.addAll(((BaseSet) data)._set);
            return;
        }

        PyObject value = null;
        if (data.__findattr__("__iter__") != null) {
            PyObject iter = data.__iter__();
            while ((value = iter.__iternext__()) != null) {
                try {
                    this._set.add(value);
                } catch (PyException e) {
                    PyObject immutable = this.asImmutable(e, value);
                    this._set.add(immutable);
                }
            }
        } else {
            int i = 0;
            while (true) {
                try {
                    value = data.__finditem__(i++);
                    if (value == null) {
                        break;
                    }
                } catch (PyException e) {
                    if (Py.matchException(e, Py.AttributeError)) {
                        throw Py.TypeError("object not iterable");
                    }
                    throw e;
                }
                try {
                    this._set.add(value);
                } catch (PyException e) {
                    PyObject immutable = this.asImmutable(e, value);
                    this._set.add(immutable);
                }
            }
        }
    }

    /**
     * The union of <code>this</code> with <code>other</code>.
     * <p/>
     * <br/>
     * (I.e. all elements that are in either set)
     *
     * @param other A <code>BaseSet</code> instance.
     * @return The union of the two sets as a new set.
     */
    public PyObject __or__(PyObject other) {
        return baseset___or__(other);
    }

    final PyObject baseset___or__(PyObject other) {
        if (!(other instanceof BaseSet)) {
            throw Py.TypeError("Not Implemented");
        }
        return baseset_union(other);
    }

    /**
     * The intersection of the <code>this</code> with <code>other</code>.
     * <p/>
     * <br/>
     * (I.e. all elements that are in both sets)
     *
     * @param other A <code>BaseSet</code> instance.
     * @return The intersection of the two sets as a new set.
     */
    public PyObject __and__(PyObject other) {
        return baseset___and__(other);
    }

    final PyObject baseset___and__(PyObject other) {
        if (!(other instanceof BaseSet)) {
            throw Py.TypeError("Not Implemented");
        }
        return baseset_intersection(other);
    }

    /**
     * The difference of the <code>this</code> with <code>other</code>.
     * <p/>
     * <br/>
     * (I.e. all elements that are in this set and not in the other)
     *
     * @param other A <code>BaseSet</code> instance.
     * @return The difference of the two sets as a new set.
     */
    public PyObject __sub__(PyObject other) {
        return baseset___sub__(other);
    }

    final PyObject baseset___sub__(PyObject other) {
        if (!(other instanceof BaseSet)) {
            throw Py.TypeError("Not Implemented");
        }
        return difference(other);
    }

    public PyObject difference(PyObject other) {
        return baseset_difference(other);
    }

    final PyObject baseset_difference(PyObject other) {
        BaseSet iterable = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other);
        Set set = iterable._set;
        BaseSet o = (BaseSet) this.getType().__call__();
        for (Iterator i = this._set.iterator(); i.hasNext();) {
            Object p = i.next();
            if (!set.contains(p)) {
                o._set.add(p);
            }
        }

        return o;
    }

    /**
     * The symmetric difference of the <code>this</code> with <code>other</code>.
     * <p/>
     * <br/>
     * (I.e. all elements that are in exactly one of the sets)
     *
     * @param other A <code>BaseSet</code> instance.
     * @return The symmetric difference of the two sets as a new set.
     */
    public PyObject __xor__(PyObject other) {
        return baseset___xor__(other);
    }

    final PyObject baseset___xor__(PyObject other) {
        if (!(other instanceof BaseSet)) {
            throw Py.TypeError("Not Implemented");
        }
        return symmetric_difference(other);
    }

    public PyObject symmetric_difference(PyObject other) {
        return baseset_symmetric_difference(other);
    }

    public PyObject baseset_symmetric_difference(PyObject other) {
        BaseSet iterable = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other);
        BaseSet o = (BaseSet) this.getType().__call__();
        for (Iterator i = this._set.iterator(); i.hasNext();) {
            Object p = i.next();
            if (!iterable._set.contains(p)) {
                o._set.add(p);
            }
        }
        for (Iterator i = iterable._set.iterator(); i.hasNext();) {
            Object p = i.next();
            if (!this._set.contains(p)) {
                o._set.add(p);
            }
        }
        return o;
    }

    /**
     * The hashCode of the set.  Only immutable instances can be hashed.
     *
     * @return The hashCode of the set.
     */
    public abstract int hashCode();

    /**
     * The length of the set.
     *
     * @return The length of the set.
     */
    public int __len__() {
        return baseset___len__();
    }

    final int baseset___len__() {
        return this._set.size();
    }

    /**
     * Determines if the instance is considered <code>true</code> by Python.
     * This implementation returns true if the set is not empty.
     *
     * @return <code>true</code> if the set is not empty, <code>false</code> otherwise
     */
    public boolean __nonzero__() {
        return baseset___nonzero__();
    }

    final boolean baseset___nonzero__() {
        return !this._set.isEmpty();
    }

    /**
     * Produce an iterable object.
     *
     * @return An iteration of the set.
     */
    public PyObject __iter__() {
        return new PySetIterator(this._set);
    }

    public boolean __contains__(PyObject other) {
        return baseset___contains__(other);
    }

    final boolean baseset___contains__(PyObject other) {
        return this._set.contains(other);
    }

    public PyObject __eq__(PyObject other) {
        return baseset___eq__(other);
    }

    final PyObject baseset___eq__(PyObject other) {
        if (other instanceof BaseSet) {
            BaseSet bs = this._binary_sanity_check(other);
            return Py.newBoolean(this._set.equals(bs._set));
        }
        return Py.Zero;
    }

    public PyObject __ne__(PyObject other) {
        return baseset___ne__(other);
    }

    final PyObject baseset___ne__(PyObject other) {
        if (other instanceof BaseSet) {
            BaseSet bs = this._binary_sanity_check(other);
            return Py.newBoolean(!this._set.equals(bs._set));
        }
        return Py.One;
    }

    public PyObject __le__(PyObject other) {
        return baseset___le__(other);
    }

    final PyObject baseset___le__(PyObject other) {
        return this.baseset_issubset(other);
    }

    public PyObject __ge__(PyObject other) {
        return baseset___ge__(other);
    }

    final PyObject baseset___ge__(PyObject other) {
        return this.baseset_issuperset(other);
    }

    public PyObject __lt__(PyObject other) {
        return baseset___lt__(other);
    }

    final PyObject baseset___lt__(PyObject other) {
        BaseSet bs = this._binary_sanity_check(other);
        return Py.newBoolean(this.__len__() < bs.__len__() && this.baseset_issubset(other).__nonzero__());
    }

    public PyObject __gt__(PyObject other) {
        return baseset___gt__(other);
    }

    public PyObject baseset___gt__(PyObject other) {
        BaseSet bs = this._binary_sanity_check(other);
        return Py.newBoolean(this.__len__() > bs.__len__() && this.baseset_issuperset(other).__nonzero__());
    }

    /**
     * Used for pickling.  Uses the module <code>setsfactory</sets> to
     * export safe constructors.
     *
     * @return a tuple of (constructor, (elements))
     */
    public PyObject __reduce__() {
        return baseset___reduce__();
    }

    final PyObject baseset___reduce__() {
        String name = getType().getFullName();
        PyObject factory = __builtin__.__import__("setsfactory");
        PyObject func = factory.__getattr__(name);
        return new PyTuple(new PyObject[] { func, new PyTuple(new PyObject[] { new PyList((PyObject) this) }) });
    }

    public PyObject __deepcopy__(PyObject memo) {
        return baseset___deepcopy__(memo);
    }

    final PyObject baseset___deepcopy__(PyObject memo) {
        PyObject copy = __builtin__.__import__("copy");
        PyObject deepcopy = copy.__getattr__("deepcopy");
        BaseSet result = (BaseSet) this.getType().__call__();
        memo.__setitem__(Py.newInteger(Py.id(this)), result);
        for (Iterator iterator = this._set.iterator(); iterator.hasNext();) {
            result._set.add(deepcopy.__call__(Py.java2py(iterator.next()), memo));
        }
        return result;
    }

    /**
     * Return this instance as a Java object.  Only coerces to Collection and subinterfaces.
     *
     * @param c The Class to coerce to.
     * @return the underlying HashSet (not a copy)
     */
    public Object __tojava__(Class c) {
        if (Collection.class.isAssignableFrom(c)) {
            return Collections.unmodifiableSet(this._set);
        }
        return super.__tojava__(c);
    }

    public PyObject baseset_union(PyObject other) {
        BaseSet result = (BaseSet) this.getType().__call__(this);
        result._update(other);
        return result;
    }

    public PyObject baseset_intersection(PyObject other) {

        PyObject little, big;
        if (!(other instanceof BaseSet)) {
            other = new PySet(other);
        }

        if (this.__len__() <= __builtin__.len(other)) {
            little = this;
            big = other;
        } else {
            little = other;
            big = this;
        }

        PyObject common = __builtin__.filter(big.__getattr__("__contains__"), little);
        return other.getType().__call__(common);
    }

    public PyObject baseset_copy() {
        BaseSet copy = (BaseSet) this.getType().__call__();
        copy._set = (HashSet) this._set.clone();
        return copy;
    }

    public PyObject baseset_issubset(PyObject other) {
        BaseSet bs = this._binary_sanity_check(other);
        if (this.__len__() > bs.__len__()) {
            return Py.Zero;
        }
        for (Iterator iterator = this._set.iterator(); iterator.hasNext();) {
            if (!bs._set.contains(iterator.next())) {
                return Py.Zero;
            }
        }
        return Py.One;
    }

    public PyObject baseset_issuperset(PyObject other) {
        BaseSet bs = this._binary_sanity_check(other);
        if (this.__len__() < bs.__len__()) {
            return Py.Zero;
        }
        for (Iterator iterator = bs._set.iterator(); iterator.hasNext();) {
            if (!this._set.contains(iterator.next())) {
                return Py.Zero;
            }
        }
        return Py.One;
    }

    final String baseset_toString() {
        return toString();
    }

    public String toString() {
        String name = getType().getFullName();
        StringBuffer buf = new StringBuffer(name).append("([");
        for (Iterator i = this._set.iterator(); i.hasNext();) {
            buf.append(((PyObject) i.next()).__repr__().toString());
            if (i.hasNext()) {
                buf.append(", ");
            }
        }
        buf.append("])");
        return buf.toString();
    }

    protected final BaseSet _binary_sanity_check(PyObject other) throws PyIgnoreMethodTag {
        try {
            return (BaseSet) other;
        } catch (ClassCastException e) {
            throw Py.TypeError("Binary operation only permitted between sets");
        }
    }

    /**
     * If the exception <code>e</code> is a <code>TypeError</code>, attempt to convert
     * the object <code>value</code> into an ImmutableSet.
     *
     * @param e     The exception thrown from a hashable operation.
     * @param value The object which was unhashable.
     * @return An ImmutableSet if available, a <code>TypeError</code> is thrown otherwise.
     */
    protected final PyObject asImmutable(PyException e, PyObject value) {
        if (Py.matchException(e, Py.TypeError)) {
            PyObject transform = value.__findattr__("_as_immutable");
            if (transform != null) {
                return transform.__call__();
            }
        }
        throw e;
    }

    //    public int size() {
    //        return this._set.size();
    //    }
    //
    //    public void clear() {
    //        this._set.clear();
    //    }
    //
    //    public boolean isEmpty() {
    //        return this._set.isEmpty();
    //    }
    //
    //    public Object[] toArray() {
    //        return this._set.toArray();
    //    }
    //
    //    public boolean add(Object o) {
    //        return this._set.add(o);
    //    }
    //
    //    public boolean contains(Object o) {
    //        return this._set.contains(o);
    //    }
    //
    //    public boolean remove(Object o) {
    //        return this._set.remove(o);
    //    }
    //
    //    public boolean addAll(Collection c) {
    //        return this._set.addAll(c);
    //    }
    //
    //    public boolean containsAll(Collection c) {
    //        return this._set.containsAll(c);
    //    }
    //
    //    public boolean removeAll(Collection c) {
    //        return this._set.removeAll(c);
    //    }
    //
    //    public boolean retainAll(Collection c) {
    //        return this._set.retainAll(c);
    //    }
    //
    //    public Iterator iterator() {
    //        return this._set.iterator();
    //    }
    //
    //    public Object[] toArray(Object a[]) {
    //        return this._set.toArray(a);
    //    }
}
TOP

Related Classes of org.python.modules.sets.BaseSet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.